﻿using OpenHardwareMonitor.Hardware;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using WindowService;

namespace ConsoleHardwareMonitor
{
    class HardwareHelper
    {
        private EndpointVolume volume = null;
        private Wmi wmi = null;
        private NetHelper netHelper = null;

        private Computer computer = null;
        private IHardware[] hardwares = null;
        private AllStateValue allStateValue = null;

        public HardwareHelper(NetHelper netHelper)
        {
            try
            {
                //获取系统音量
                this.wmi = new Wmi();
                this.volume = new EndpointVolume();
                this.computer = new Computer();

                this.netHelper = netHelper;

                this.computer.CPUEnabled = true;
                this.computer.HDDEnabled = true;
                this.computer.MainboardEnabled = true;
                this.computer.RAMEnabled = true;
                this.computer.GPUEnabled = true;
                this.computer.FanControllerEnabled = true;
                this.computer.Open();
                this.hardwares = computer.Hardware;
            }
            catch (Exception e)
            {
                Log.WriteLog("HardwareHelper init failed, error: " + e.Message, LogType.Error);
            }

            //重置全状态数据包
            this.resetAllStateValue();
            //采集全状态值
            this.collectAllStateValue();

        }
        private HeartbeatValue getHeartbeatValue(){
            //采集全状态值
            collectAllStateValue();
            //返回心跳包
            HeartbeatValue heartbeatValue = new HeartbeatValue();
            heartbeatValue.mac = (wmi == null) ? "" : wmi.getMac();
            heartbeatValue.netType = netHelper.getNetType();
            heartbeatValue.linkState = netHelper.getLinkState();
            heartbeatValue.wSpeed = netHelper.getNetSpeed();
            heartbeatValue.wsig = netHelper.getWsig();
            heartbeatValue.cpuTemperature = allStateValue.cpuTemperature;

            return heartbeatValue;
        }
        //采集全状态值
        public void collectAllStateValue()
        {
            ISensor[] sensors = null;

            foreach (IHardware hardware in hardwares)
            {
                hardware.Update();
                switch (hardware.HardwareType)
                {
                    case HardwareType.CPU:
                        sensors = hardware.Sensors;
                        foreach (ISensor sensor in sensors)
                        {
                            switch (sensor.SensorType)
                            {
                                case SensorType.Temperature:
                                    allStateValue.cpuTemperature.SetValue(sensor.Value);
                                    break;
                                case SensorType.Load:
                                    allStateValue.cpuLoad.SetValue(sensor.Value);
                                    break;
                            }
                        }
                        break;
                    case HardwareType.GpuAti:
                    case HardwareType.GpuNvidia:
                        sensors = hardware.Sensors;
                        foreach (ISensor sensor in sensors)
                        {
                            switch (sensor.SensorType)
                            {
                                case SensorType.Temperature:
                                    allStateValue.gpuTemperature.SetValue(sensor.Value);
                                    break;
                            }
                        }
                        break;
                    case HardwareType.Mainboard:
                        sensors = hardware.Sensors;
                        foreach (ISensor sensor in sensors)
                        {
                            switch (sensor.SensorType)
                            {
                                case SensorType.Temperature:
                                    allStateValue.mainboardTemperature.SetValue(sensor.Value);
                                    break;
                            }
                        }
                        break;
                    case HardwareType.HDD:
                        sensors = hardware.Sensors;
                        foreach (ISensor sensor in sensors)
                        {
                            switch (sensor.SensorType)
                            {
                                case SensorType.Temperature:
                                    allStateValue.hddTemperature.SetValue(sensor.Value);
                                    break;
                            }
                        }
                        break;
                }
            }
            //硬盘剩余空间
            DriveInfo[] drives = DriveInfo.GetDrives();
            allStateValue.hddLoad = new HDDLoad();
            allStateValue.hddLoad.sections = new List<Section>();
            foreach (DriveInfo drive in drives)
            {
                if (drive.DriveType == DriveType.Fixed)
                {
                    Section section = new Section();
                    section.name = drive.Name;
                    section.value = 1 - (float)drive.TotalFreeSpace / drive.TotalSize;
                    allStateValue.hddLoad.sections.Add(section);
                }
            }
            allStateValue.linkState = netHelper.getLinkState();
            allStateValue.netType = netHelper.getNetType();
            allStateValue.wsig = netHelper.getWsig();
            allStateValue.wSpeed = netHelper.getNetSpeed();

            Log.WriteLog("HardwareHelper Collect All State Value: " + getAllStatePostParameters(), LogType.Trace);
        }

        public void resetAllStateValue()
        {
            allStateValue = new AllStateValue();
            allStateValue.mac = (wmi == null) ? "" : wmi.getMac();
            allStateValue.netType = NetType.NET;
            allStateValue.linkState = LinkState.OK;
            allStateValue.wsig = "";
            allStateValue.wSpeed = "";
            allStateValue.cpuTemperature = new CpuTemperature();
            allStateValue.gpuTemperature = new GpuTemperature();
            allStateValue.mainboardTemperature = new MainboardTemperature();
            allStateValue.hddTemperature = new HDDTemperature();
            allStateValue.cpuLoad = new CPULoad();
            allStateValue.volume = (volume == null) ? 0 : volume.MasterVolume;
            //HDDLoad 独立控制重置频率，这里不要重置

            Log.WriteLog("HardwareHelper Reset All State Value: " + getAllStatePostParameters(), LogType.Trace);
        }
        public IDictionary<string, string> getHeartbeatPostParameters()
        {
            //保存POST参数
            IDictionary<string, string> postParams = new Dictionary<string, string>();
            //采集全状态数据
            HeartbeatValue heartbeatValue = getHeartbeatValue();
            postParams.Add("mac", heartbeatValue.mac);
            postParams.Add("netType", heartbeatValue.netType.ToString());
            postParams.Add("linkState", heartbeatValue.linkState.ToString());
            postParams.Add("wsig", heartbeatValue.wsig.ToString());
            postParams.Add("wSpeed", heartbeatValue.wSpeed.ToString());
            postParams.Add("cpuMinTemp", heartbeatValue.cpuTemperature.minValue.ToString());
            postParams.Add("cpuMaxTemp", heartbeatValue.cpuTemperature.maxValue.ToString());
            postParams.Add("cpuAveTemp", heartbeatValue.cpuTemperature.aveValue.ToString());

            return postParams;
        }
        public string getAllStatePostParameters()
        {
            //IDictionary<string, string> postParams = new Dictionary<string, string>();
            //postParams.Add("mac", allStateValue.mac);
            //postParams.Add("netType", allStateValue.netType.ToString());
            //postParams.Add("linkState", allStateValue.linkState.ToString());
            //postParams.Add("wsig", allStateValue.wsig.ToString());
            //postParams.Add("wSpeed", allStateValue.wSpeed.ToString());
            //postParams.Add("cpuMinTemp", allStateValue.cpuTemperature.minValue.ToString());
            //postParams.Add("cpuMaxTemp", allStateValue.cpuTemperature.maxValue.ToString());
            //postParams.Add("cpuAveTemp", allStateValue.cpuTemperature.aveValue.ToString());
            //postParams.Add("gpuMinTemp", allStateValue.gpuTemperature.minValue.ToString());
            //postParams.Add("gpuMaxTemp", allStateValue.gpuTemperature.maxValue.ToString());
            //postParams.Add("gpuAveTemp", allStateValue.gpuTemperature.aveValue.ToString());
            //postParams.Add("mainboardMinTemp", allStateValue.mainboardTemperature.minValue.ToString());
            //postParams.Add("mainboardMaxTemp", allStateValue.mainboardTemperature.maxValue.ToString());
            //postParams.Add("mainboardAveTemp", allStateValue.mainboardTemperature.aveValue.ToString());
            //postParams.Add("hddMinTemp", allStateValue.hddTemperature.minValue.ToString());
            //postParams.Add("hddMaxTemp", allStateValue.hddTemperature.maxValue.ToString());
            //postParams.Add("hddAveTemp", allStateValue.hddTemperature.aveValue.ToString());
            //postParams.Add("cpuMinLoad", allStateValue.cpuLoad.minValue.ToString());
            //postParams.Add("cpuMaxLoad", allStateValue.cpuLoad.maxValue.ToString());
            //postParams.Add("cpuAveLoad", allStateValue.cpuLoad.aveValue.ToString());
            //postParams.Add("hddLoad", allStateValue.hddLoad.ToString());
            //postParams.Add("volume", allStateValue.volume.ToString());

            if (allStateValue == null)
            {
                resetAllStateValue();
            }
            Newtonsoft.Json.Linq.JObject obj = Newtonsoft.Json.Linq.JObject.FromObject(allStateValue);

            return obj.ToString();
        }

    }
}
